package com.ruibang.glass.produce.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruibang.glass.produce.domain.resp.MonitorUpdate;
import com.ruibang.glass.produce.domain.resp.UnitResp;
import com.ruibang.glass.produce.entity.MonitorPoint;
import com.ruibang.glass.produce.entity.MonitorType;
import com.ruibang.glass.produce.entity.TypeUnit;
import com.ruibang.glass.produce.mapper.UnitMapper;
import com.ruibang.glass.produce.service.MonitorPointService;
import com.ruibang.glass.produce.service.MonitorTypeService;
import com.ruibang.glass.produce.service.UnitService;
import com.teaming.cloud.framework2.common.model.ResultBody;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author: songJinKang
 * @CreateTime: 2023-11-15  20:31
 * @Description: TODO
 * @Version: 1.0
 */

@Slf4j
@Service
public class UnitServiceImpl extends ServiceImpl<UnitMapper, TypeUnit> implements UnitService {

    @Autowired
    private MonitorPointService monitorPointService;

    @Autowired
    private MonitorTypeService monitorTypeService;

    @Override
    public void updateUnit(List<TypeUnit> units) {
        if (CollectionUtils.isNotEmpty(units)) {
            for (TypeUnit unit : units) {
                if (CollectionUtils.isNotEmpty(unit.getUnitResp())) {
                    for (UnitResp unitResp : unit.getUnitResp()) {
                        if (unitResp != null) {
                            if (unitResp.getId() != null) {
                                Map<String, Object> map = new HashMap<>(16);
                                map.put("unit", unitResp.getIsNew());
                                map.put("unitName", unitResp.getUnitName());
                                map.put("typeId", unit.getTypeId());
                                map.put("id", unitResp.getId());
                                baseMapper.updateUnit(map);
                                if (StringUtils.isNotBlank(unitResp.getIsNew())) {
                                    MonitorUpdate monitorUpdate = new MonitorUpdate();
                                    monitorUpdate.setNewUnit(unitResp.getIsNew());
                                    monitorUpdate.setOldUnit(unitResp.getIsOld());
                                    monitorUpdate.setTypeId(unit.getTypeId());
                                    monitorPointService.updateUnit(monitorUpdate);
                                }
                            } else {
                                TypeUnit tu = new TypeUnit();
                                tu.setUnit(unitResp.getIsNew());
                                tu.setTypeId(unit.getTypeId());
                                if (StringUtils.isNotBlank(unitResp.getUnitName())) {
                                    tu.setUnitName(unitResp.getUnitName());
                                }
                                this.save(tu);
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    public ResultBody deleteById(String unitId) {
        TypeUnit unit = this.getById(unitId);
        Map<String, String> param = new HashMap<>(16);
        param.put("unit", unit.getUnit());
        param.put("typeId", unit.getTypeId());
        List<MonitorPoint> monitorPoints = baseMapper.monitorByUnitId(param);
        if (monitorPoints.size() > 0) {
            return ResultBody.fail(200, "该单位被一些监测点正在使用不可以被删除！");
        } else {
            this.removeById(String.valueOf(unitId));
            return ResultBody.success();
        }
    }

    @Override
    public ResultBody allTypeUnit() {
        List<TypeUnit> typeUnits = this.list();
        List<TypeUnit> all = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(typeUnits)) {
            List<String> unitIds = typeUnits.stream().map(TypeUnit::getTypeId).distinct().collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(unitIds)) {
                unitIds.forEach(e -> {
                    TypeUnit unit = new TypeUnit();
                    all.add(unit);
                    unit.setTypeId(e);
                });
                Map<String, List<TypeUnit>> collect = typeUnits.stream().collect(Collectors.groupingBy(TypeUnit::getTypeId));
                collect.forEach((k, v) -> {
                    for (TypeUnit unit : all) {
                        if (unit.getTypeId().equals(k)) {
                            List<UnitResp> newUnitResps = new ArrayList<>();
                            for (TypeUnit typeUnit : v) {
                                UnitResp newUnitResp = new UnitResp();
                                newUnitResps.add(newUnitResp);
                                newUnitResp.setId(typeUnit.getId());
                                newUnitResp.setIsOld(typeUnit.getUnit());
                                newUnitResp.setUnitName(typeUnit.getUnitName());
                            }
                            unit.setUnitResp(newUnitResps);
                        }
                    }
                });
                List<MonitorType> monitorTypes = monitorTypeService.list();
                if (CollectionUtils.isNotEmpty(monitorTypes)) {
                    monitorTypes.forEach(e -> {
                        for (TypeUnit unit : all) {
                            if (unit.getTypeId().equals(e.getTypeId())) {
                                unit.setTypeName(e.getTypeName());
                            }
                        }
                    });
                }
                List<String> allIds = all.stream().map(TypeUnit::getTypeId).collect(Collectors.toList());
                List<String> monitorIds = monitorTypes.stream().map(MonitorType::getTypeId).collect(Collectors.toList());
                List<String> filterIds = Stream.concat(allIds.stream(), monitorIds.stream()).collect(Collectors.groupingBy(Function.identity(), Collectors.counting())).entrySet().stream().filter(e -> e.getValue() == 1).map(Map.Entry::getKey).collect(Collectors.toList());
                filterIds.forEach(e -> {
                    for (MonitorType monitorType : monitorTypes) {
                        if (e.equals(monitorType.getTypeId())) {
                            TypeUnit unit = new TypeUnit();
                            all.add(unit);
                            unit.setTypeId(monitorType.getTypeId());
                            unit.setTypeName(monitorType.getTypeName());
                        }
                    }
                });
            }
        }
        return ResultBody.success(all);
    }
}
